package cn.edu.sysu.dao;

import java.sql.Connection;
import java.sql.Date;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections.map.HashedMap;

import cn.edu.sysu.dto.IssueDto;
import cn.edu.sysu.dto.ProblemDto;
import cn.edu.sysu.dto.SolutionDto;
import cn.edu.sysu.dto.UserDto;
import cn.edu.sysu.util.Transaction;

public enum IssueDao {

	INSTANCE;

	private static final String INSERT_ISSUE = "insert into cws_issue (problem_id,solution_user_id,revision,content, post_user_id,reply_to,post_time) values (?,?,?,?,?,?,?)";

	public void saveIssue(Transaction transaction, IssueDto issue) {
		ResultSet rs =null;
		PreparedStatement ps =null;
		try {
			transaction.begin();

			Connection conn = transaction.getResource(Connection.class);
			ps = conn.prepareStatement(INSERT_ISSUE);
			ps.setInt(1, issue.getProblem_id());
			ps.setInt(2, issue.getSolution_user_id());
			ps.setInt(3, issue.getRevision());
			ps.setString(4, issue.getContent());
			ps.setInt(5,issue.getIssue_user_id());
			ps.setInt(6, issue.getReply_to());
			ps.setTimestamp(7, new Timestamp( issue.getPost_time().getTime()));

			ps.executeUpdate();
			transaction.commit();

			System.out.println("finish insert an issue ");

		} catch (SQLException se) {

			se.printStackTrace();

		} finally {
			if (rs != null) {
				try {
					rs.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
			if (ps != null) {
				try {
					ps.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
			transaction.preDestroy();
		}

	}

	private static final String GET_ISSUE_BY_PROBLEM = "select * from cws_issue ci where problem_id=?";
	public List<IssueDto> getIssueByProblem(Transaction transaction, int problemId) {
		ResultSet rs =null;
		PreparedStatement ps =null;
		try {
			transaction.begin();
			Connection conn = transaction.getResource(Connection.class);
			ps = conn.prepareStatement(GET_ISSUE_BY_PROBLEM);
			ps.setInt(1, problemId);
			rs = ps.executeQuery();
			List<IssueDto> issues = new ArrayList<IssueDto>();
			while(rs.next()){
				issues.add(makeIssueDto(transaction, rs)) ;
			}

			return issues;

		} catch (SQLException se) {

			se.printStackTrace();

		} finally {
			if (rs != null) {
				try {
					rs.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
			if (ps != null) {
				try {
					ps.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
			transaction.preDestroy();
		}

		return new ArrayList<IssueDto>();
	}
	private IssueDto makeIssueDto(Transaction transaction, ResultSet rs) throws SQLException {

		int issue_id = rs.getInt(1);
		int problem_id = rs.getInt(2);
		int solution_user_id = rs.getInt(3);
		int revision = rs.getInt(4);
		String content = rs.getString(5);
		int post_user_id = rs.getInt(6);
		int reply_to=rs.getInt(7);
		Date post_time = new Date(rs.getTimestamp(8).getTime());

		return new IssueDto(issue_id, solution_user_id, problem_id, revision, content, post_user_id, reply_to, post_time);
	}

	private static final String GET_ISSUE_BY_PROBLEM_AND_USER = "select * from cws_issue ci where problem_id=? and solution_user_id=?";
	public List<IssueDto> getIssueByProblemAndUser(Transaction transaction,
			int problem_id, int user_id) {
		ResultSet rs =null;
		PreparedStatement ps =null;
		try {
			transaction.begin();
			Connection conn = transaction.getResource(Connection.class);
			ps = conn.prepareStatement(GET_ISSUE_BY_PROBLEM_AND_USER);
			ps.setInt(1, problem_id);
			ps.setInt(2, user_id);
			rs = ps.executeQuery();
			List<IssueDto> issues = new ArrayList<IssueDto>();
			while(rs.next()){
				issues.add(makeIssueDto(transaction, rs)) ;
			}

			return issues;

		} catch (SQLException se) {

			se.printStackTrace();

		} finally {
			if (rs != null) {
				try {
					rs.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
			if (ps != null) {
				try {
					ps.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
			transaction.preDestroy();
		}

		return new ArrayList<IssueDto>();
	}
}
